<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta content="Cask Data, Inc." name="author" />
<meta content="Copyright © 2016-2017 Cask Data, Inc." name="copyright" />


    <meta name="git_release" content="6.1.1">
    <meta name="git_hash" content="05fbac36f9f7aadeb44f5728cea35136dbc243e5">
    <meta name="git_timestamp" content="2020-02-09 08:22:47 +0800">
    <title>Plugin Basics</title>

    <link rel="stylesheet" href="../../_static/cdap-bootstrap.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/bootstrap-3.3.6/css/bootstrap.min.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/bootstrap-3.3.6/css/bootstrap-theme.min.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/css/bootstrap-sphinx.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/css/cdap-dynamicscrollspy-4.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/css/jquery.mCustomScrollbar.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/css/cdap-jquery.mCustomScrollbar.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/css/abixTreeList-2.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/cdap-bootstrap.css" type="text/css" />

    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '6.1.1',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  false
      };
    </script>
    <script type="text/javascript" src="../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../_static/doctools.js"></script>
    <script type="text/javascript" src="../../_static/language_data.js"></script>

    <link rel="shortcut icon" href="../../_static/favicon.ico"/>
    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" />
    <link rel="top" title="Cask Data Application Platform 6.1.1 Documentation" href="../../index.html" />
    <link rel="up" title="Developing Plugins" href="index.html" />
    <link rel="next" title="Creating a Plugin" href="creating-a-plugin.html" />
    <link rel="prev" title="Developing Plugins" href="index.html" />
    <!-- block extrahead -->
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
    <meta name="apple-mobile-web-app-capable" content="yes">
    <!-- block extrahead end -->

</head>
<body role="document">

<!-- block navbar -->
<div id="navbar" class="navbar navbar-inverse navbar-default navbar-fixed-top">
    <div class="container-fluid">
      <div class="row">
        <div class="navbar-header">
          <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
          <a class="navbar-brand" href="../../table-of-contents/../../index.html">
            <span><img alt="CDAP logo" src="../../_static/cdap_logo.svg"/></span>
          </a>

          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>

          <div class="pull-right">
            <div class="dropdown version-dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown"
                role="button" aria-haspopup="true" aria-expanded="false">
                v 6.1.1 <span class="caret"></span>
              </a>
              <ul class="dropdown-menu">
                <li><a href="//docs.cdap.io/cdap/5.1.2/en/index.html">v 5.1.2</a></li>
                <li><a href="//docs.cdap.io/cdap/4.3.4/en/index.html">v 4.3.4</a></li>
              </ul>
            </div>
          </div>
          <form class="navbar-form navbar-right navbar-search" action="../../search.html" method="get">
            <div class="form-group">
              <div class="navbar-search-image material-icons"></div>
              <input type="text" name="q" class="form-control" placeholder="  Search" />
            </div>
            <input type="hidden" name="check_keywords" value="yes" />
            <input type="hidden" name="area" value="default" />
          </form>

          <div class="collapse navbar-collapse nav-collapse navbar-right navbar-navigation">
            <ul class="nav navbar-nav"><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link " href="../../table-of-contents/../../index.html">简介</a></li><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link current" href="../../table-of-contents/../../guides.html">手册</a></li><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link " href="../../table-of-contents/../../reference-manual/index.html">参考</a></li><li class="docsite-nav-tab-container"><a class="docsite-nav-tab-link " href="../../table-of-contents/../../faqs/index.html">帮助</a></li>
            </ul>
          </div>

        </div>
      </div>
    </div>
  </div><!-- block navbar end -->
<!-- block main content -->
<div class="main-container container">
  <div class="row"><div class="col-md-2">
      <div id="sidebar" class="bs-sidenav scrollable-y-outside" role="complementary">
<!-- theme_manual: developer-manual -->
<!-- theme_manual_highlight: guides -->
<!-- sidebar_title_link: ../../table-of-contents/../../guides.html -->

  <div role="note" aria-label="manuals links"><h3><a href="../../table-of-contents/../../guides.html">Guides</a></h3>

    <ul class="this-page-menu">
      <li class="toctree-l1"><a href="../../table-of-contents/../../user-guide/index.html" rel="nofollow">用户手册</a>
      </li>
      <li class="toctree-l1"><b><a href="../../table-of-contents/../../developer-manual/index.html" rel="nofollow">开发手册</a></b>
      <nav class="pagenav">
      <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../index.html"> 简介</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../getting-started/index.html"> 入门指南</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../getting-started/sandbox/index.html">CDAP Sandbox</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../getting-started/sandbox/zip.html">二进制 Zip 文件</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../getting-started/sandbox/zip.html#cdap-sandbox">启动和停止 CDAP Sandbox</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../getting-started/sandbox/virtual-machine.html">虚拟机镜像</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../getting-started/sandbox/docker.html">Docker 镜像</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../getting-started/quick-start.html">快速入门</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../getting-started/dev-env.html">搭建开发环境</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../getting-started/start-stop-cdap.html">启动和停止 CDAP</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../getting-started/building-apps.html">构建并运行应用</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../overview/index.html"> 概述</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../overview/anatomy.html"> 大数据应用剖析</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../overview/modes.html"> 模式和组件</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../overview/abstractions.html"> 核心概念</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../overview/interfaces.html"> 编程接口</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../building-blocks/index.html"> 抽象概念</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/core.html"> Core Abstractions</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/applications.html"> Applications</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/datasets/index.html"> Datasets</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../building-blocks/datasets/overview.html"> Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../building-blocks/datasets/table.html"> Table API</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../building-blocks/datasets/fileset.html"> FileSets</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../building-blocks/datasets/partitioned-fileset.html"> Partitioned FileSets</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../building-blocks/datasets/time-partitioned-fileset.html"> TimePartitioned FileSets</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../building-blocks/datasets/system-custom.html"> System and Custom Datasets</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../building-blocks/datasets/permissions.html"> Dataset Permissions</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../building-blocks/datasets/cube.html"> Cube Dataset</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/mapreduce-programs.html"> MapReduce Programs</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/plugins.html"> Plugins</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/schedules.html"> Schedules</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/secure-keys.html"> Secure Keys</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/services.html"> Services</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/spark-programs.html"> Spark Programs</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/workers.html"> Workers</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/workflows.html"> Workflows</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/artifacts.html"> Artifacts</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/program-lifecycle.html"> Program Lifecycle</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/namespaces.html"> Namespaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/transaction-system.html"> Transaction System</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../building-blocks/transactional-messaging-system.html"> Transactional Messaging System</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../metadata/index.html"> 元数据</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../metadata/system-metadata.html"> System Metadata</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../metadata/discovery-lineage.html"> Discovery and Lineage</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../metadata/field-lineage.html"> Field Level Lineage</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../metadata/audit-logging.html"> Audit Logging</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../metadata/metadata-ui.html"> CDAP Metadata UI</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../metadata/programmatic-metadata.html"> Accessing metadata programmatically</a></li>
</ul>
</li>
<li class="toctree-l1 current"><a class="reference internal" href="../index.html"> 数据流管道</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../concepts-design.html"> Concepts and Design</a></li>
<li class="toctree-l2"><a class="reference internal" href="../getting-started.html"> Getting Started</a></li>
<li class="toctree-l2"><a class="reference internal" href="../studio.html"> CDAP Studio</a></li>
<li class="toctree-l2"><a class="reference internal" href="../creating-pipelines.html"> Creating Pipelines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../running-pipelines.html"> Running Pipelines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../plugin-management.html"> Plugin Management</a></li>
<li class="toctree-l2"><a class="reference internal" href="../plugins/index.html"> Plugin Reference</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../plugins/actions/index.html"> Action Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../plugins/sources/index.html"> Source Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../plugins/transforms/index.html"> Transform Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../plugins/analytics/index.html"> Analytic Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../plugins/sinks/index.html"> Sink Plugins</a><ul class="simple">
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../plugins/shared-plugins/index.html"> Shared Plugins</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../plugins/shared-plugins/core.html">CoreValidator</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../plugins/post-run-plugins/index.html"> Post-run Plugins</a><ul class="simple">
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../developing-pipelines.html"> Developing Pipelines</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="index.html"> Developing Plugins</a><ul class="current">
<li class="toctree-l3 current"><a class="current reference internal" href="#">Plugin Basics</a></li>
<li class="toctree-l3"><a class="reference internal" href="creating-a-plugin.html">Creating a Plugin</a></li>
<li class="toctree-l3"><a class="reference internal" href="presentation-plugins.html">Plugin Presentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="testing-plugins.html">Testing Plugins</a></li>
<li class="toctree-l3"><a class="reference internal" href="packaging-plugins.html">Packaging Plugins</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../how-cdap-pipelines-work.html"> How CDAP Pipelines Work</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../cloud-runtimes/index.html"> 云平台运行</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../cloud-runtimes/concepts/index.html"> Concepts</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../cloud-runtimes/provisioners/index.html"> Provisioners</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../cloud-runtimes/provisioners/gcp-dataproc.html">Google Dataproc</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../cloud-runtimes/provisioners/aws-emr.html">Amazon Elastic MapReduce</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../cloud-runtimes/provisioners/remote-hadoop.html">Remote Hadoop</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../cloud-runtimes/profiles/index.html"> Profiles</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../cloud-runtimes/profiles/creating-profiles.html">Creating Profiles</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../cloud-runtimes/profiles/assigning-profiles.html">Assigning Profiles</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../cloud-runtimes/profiles/admin-controls.html">Admin Controls</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../cloud-runtimes/example/index.html"> Example</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../security/index.html"> 安全</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../security/client-authentication.html">Client Authentication</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../security/cdap-authentication-clients-java.html">CDAP Authentication Client for Java</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../security/cdap-authentication-clients-python.html">CDAP Authentication Client for Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../security/custom-authentication.html">Custom Authentication</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../security/authorization-extensions.html">Authorization Extensions</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../testing/index.html"> 测试和调试</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../testing/testing.html"> Testing a CDAP Application</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../testing/debugging.html"> Debugging</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../testing/troubleshooting.html"> Troubleshooting</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../ingesting-tools/index.html"> 数据融合</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../ingesting-tools/cdap-stream-clients-java.html">CDAP Stream Client for Java</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../ingesting-tools/cdap-stream-clients-python.html">CDAP Stream Client for Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../ingesting-tools/cdap-stream-clients-ruby.html">CDAP Stream Client for Ruby</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../ingesting-tools/cdap-flume.html">CDAP Flume</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../data-exploration/index.html"> 数据探索</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../data-exploration/filesets.html"> Fileset Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../data-exploration/tables.html"> Table Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../data-exploration/object-mapped-tables.html"> ObjectMappedTable Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../data-exploration/custom-datasets.html"> Custom Dataset Exploration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../data-exploration/hive-execution-engines.html"> Hive Execution Engines</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../advanced/index.html"> 高级主题</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../advanced/application-logback.html"> Application Logback</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../advanced/best-practices.html"> Best Practices</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../advanced/class-loading.html"> Class Loading</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../advanced/configuring-resources.html"> Configuring Program Resources</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../advanced/program-retry-policies.html"> Program Retry Policies</a></li>
</ul>
</li>
</ul>
</nav>
      </li>
      <li class="toctree-l1"><a href="../../table-of-contents/../../admin-manual/index.html" rel="nofollow">管理手册</a>
      </li>
      <li class="toctree-l1"><a href="../../table-of-contents/../../integrations/index.html" rel="nofollow">集成手册</a>
      </li>
      <li class="toctree-l1"><a href="../../table-of-contents/../../examples-manual/index.html" rel="nofollow">最佳实践</a>
      </li>
    </ul>
  </div></div>
    </div><div class="col-md-8 content" id="main-content">
    
  <div class="section" id="plugin-basics">
<span id="cdap-pipelines-developing-plugin-basics"></span><h1>Plugin Basics<a class="headerlink" href="#plugin-basics" title="Permalink to this headline">🔗</a></h1>
<div class="section" id="plugin-types">
<h2>Plugin Types<a class="headerlink" href="#plugin-types" title="Permalink to this headline">🔗</a></h2>
<p>In CDAP pipelines, these plugin types are presently used:</p>
<ul class="simple">
<li>Action (<em>action</em>, restricted to batch pipelines)</li>
<li>Batch Source (<em>batchsource</em>, restricted to batch pipelines)</li>
<li>Batch Sink (<em>batchsink</em>)</li>
<li>Streaming Source (<em>streamingsource</em>, restricted to real-time pipelines)</li>
<li>Transformation (<em>transform</em>)</li>
<li>Error Transformation (<em>errortransform</em>)</li>
<li>Batch Aggregator (<em>batchaggregator</em>)</li>
<li>Batch Joiner (<em>batchjoiner</em>)</li>
<li>Spark Compute (<em>sparkcompute</em>)</li>
<li>Spark Sink (<em>sparksink</em>, restricted to batch pipelines)</li>
<li>Windower (<em>windower</em>, restricted to real-time pipelines)</li>
<li>Post-run Action (<em>postaction</em>, restricted to batch pipelines)</li>
</ul>
<p>In the CDAP Pipelines UI, all Batch Aggregator, Batch Joiner, Spark Compute, and Spark Sink
plugins are grouped under the Analytics section. All Transformation and Windower plugins
are grouped under the Transforms section.</p>
</div>
<div class="section" id="maven-archetypes">
<span id="cdap-pipelines-developing-plugin-basics-maven-archetypes"></span><h2>Maven Archetypes<a class="headerlink" href="#maven-archetypes" title="Permalink to this headline">🔗</a></h2>
<p>To get started on creating a custom plugin, you can use the Maven archetype to create your project:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">cdap-data-pipeline-plugins-archetype</span></code> (contains batch, Spark plugin, and other types)</li>
</ul>
<p>This command will create a project from an archetype:</p>
<div class="highlight container">
<pre class="literal-block">
<span class="gp">$</span> mvn archetype:generate \
      -DarchetypeGroupId=io.cdap.cdap \
      -DarchetypeArtifactId=cdap-data-pipeline-plugins-archetype \
      -DarchetypeVersion=6.1.1 \
      -DgroupId=org.example.plugin
</pre>
</div>
<p><strong>Note:</strong> Replace the <em>groupId</em> parameter (<code class="docutils literal notranslate"><span class="pre">org.example.plugin</span></code>) with your own
organization, but it must not be replaced with <code class="docutils literal notranslate"><span class="pre">io.cdap.cdap</span></code>.</p>
<p>Complete examples for each archetype:</p>
<div class="highlight container">
<pre class="literal-block">
$ mvn archetype:generate -DarchetypeGroupId=io.cdap.cdap -DarchetypeArtifactId=cdap-data-pipeline-plugins-archetype -DarchetypeVersion=6.1.1 -DgroupId=org.example.plugin
</pre>
</div>
<p>Maven supplies a guide to the naming convention used above at
<a class="reference external" href="https://maven.apache.org/guides/mini/guide-naming-conventions.html">https://maven.apache.org/guides/mini/guide-naming-conventions.html</a>.</p>
</div>
<div class="section" id="class-annotations">
<h2>Class Annotations<a class="headerlink" href="#class-annotations" title="Permalink to this headline">🔗</a></h2>
<p>These annotations are used for plugin classes:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">&#64;Plugin</span></code>: The class to be exposed as a plugin needs to be annotated with the <code class="docutils literal notranslate"><span class="pre">&#64;Plugin</span></code>
annotation and the type of the plugin must be specified.</li>
<li><code class="docutils literal notranslate"><span class="pre">&#64;Name</span></code>: Annotation used to name the plugin.</li>
<li><code class="docutils literal notranslate"><span class="pre">&#64;Description</span></code>: Annotation used to add a description of the plugin.</li>
<li><code class="docutils literal notranslate"><span class="pre">&#64;Requirements</span></code>: Annotation used to specify the <a class="reference external" href="../../../reference-manual/javadocs/io/cdap/cdap/api/annotation/Requirements.html">Requirements</a> needed by a plugin to run successfully.</li>
</ul>
</div>
<div class="section" id="plugin-configuration">
<h2>Plugin Configuration<a class="headerlink" href="#plugin-configuration" title="Permalink to this headline">🔗</a></h2>
<p>Each plugin can define a plugin config that specifies what properties the plugin requires.
When a user creates a pipeline, they will need to provide these properties in order to
use the plugin. This is done by extending the <code class="docutils literal notranslate"><span class="pre">PluginConfig</span></code> class, and populating that
class with the fields your plugin requires. Each field can be annotated to provide more
information to users:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">&#64;Name</span></code>: The name of the field. Defaults to the Java field name. You may want to use this
if you want the user-facing name to use syntax that is not legal Java syntax.</li>
<li><code class="docutils literal notranslate"><span class="pre">&#64;Description</span></code>: A description for the field.</li>
<li><code class="docutils literal notranslate"><span class="pre">&#64;Nullable</span></code>: Indicates that the specific configuration property is
optional. Such a plugin class can be used without that property being specified.</li>
</ul>
<p>At this time, fields in a <code class="docutils literal notranslate"><span class="pre">PluginConfig</span></code> must be primitive Java types (boxed or unboxed).</p>
<p>Example:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="nd">@Plugin</span><span class="p">(</span><span class="n">type</span> <span class="o">=</span> <span class="n">BatchSource</span><span class="p">.</span><span class="na">PLUGIN_TYPE</span><span class="p">)</span>
<span class="nd">@Name</span><span class="p">(</span><span class="s">&quot;MyBatchSource&quot;</span><span class="p">)</span>
<span class="nd">@Description</span><span class="p">(</span><span class="s">&quot;This is my Batch Source.&quot;</span><span class="p">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyBatchSource</span> <span class="kd">extends</span> <span class="n">BatchSource</span><span class="o">&lt;</span><span class="n">LongWritable</span><span class="p">,</span> <span class="n">Text</span><span class="p">,</span> <span class="n">StructuredRecord</span><span class="o">&gt;</span> <span class="p">{</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">Conf</span> <span class="n">conf</span><span class="p">;</span>

  <span class="kd">public</span> <span class="nf">MyBatchSource</span><span class="p">(</span><span class="n">Conf</span> <span class="n">conf</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="na">conf</span> <span class="o">=</span> <span class="n">conf</span><span class="p">;</span>
  <span class="p">)</span>

  <span class="kd">public</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">Conf</span> <span class="kd">extends</span> <span class="n">PluginConfig</span> <span class="p">{</span>
    <span class="nd">@Name</span><span class="p">(</span><span class="s">&quot;input-path&quot;</span><span class="p">)</span>
    <span class="nd">@Description</span><span class="p">(</span><span class="s">&quot;Input path for the source.&quot;</span><span class="p">)</span>
    <span class="kd">private</span> <span class="n">String</span> <span class="n">inputPath</span><span class="p">;</span>

    <span class="nd">@Nullable</span>
    <span class="nd">@Description</span><span class="p">(</span><span class="s">&quot;Whether to clean up the previous run&#39;s output. Defaults to false.&quot;</span><span class="p">)</span>
    <span class="kd">private</span> <span class="n">Boolean</span> <span class="n">cleanOutput</span><span class="p">;</span>

    <span class="kd">public</span> <span class="nf">Conf</span><span class="p">()</span> <span class="p">{</span>
      <span class="n">cleanOutput</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="p">...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In this example, we have a plugin of type <code class="docutils literal notranslate"><span class="pre">batchsource</span></code>, named <code class="docutils literal notranslate"><span class="pre">MyBatchSource</span></code>.
This plugin takes two configuration properties. The first is named <code class="docutils literal notranslate"><span class="pre">input-path</span></code> and is required.
The second is named <code class="docutils literal notranslate"><span class="pre">cleanOutput</span></code> and is optional. Note that optional configuration fields should
have their default values set in the no-argument constructor.</p>
</div>
<div class="section" id="plugin-data-types">
<h2>Plugin Data Types<a class="headerlink" href="#plugin-data-types" title="Permalink to this headline">🔗</a></h2>
<p>Plugins support several physical data types: null, boolean, int, long, float, double, string, array, map, enum, union,
and record. They also support several logical data types: date, time-millis, time-micros, timestamp-millis,
and timestamp-micros. Logical types represent some abstract concept but are internally represented with a corresponding
physical type. The date logical type is an integer that holds the number of days since the Unix epoch. The time-millis
logical type is an integer that holds the number of milliseconds since midnight. The time-micros logical type is
a long that holds the number of microseconds since midnight. The timestamp-millis logical type is a long that holds
the number of milliseconds since the Unix epoch. The timestamp-micros logical type is a long that holds the number
of microseconds since the Unix epoch.</p>
<p>To create a schema field of a logical type:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="n">Schema</span> <span class="n">schema</span> <span class="o">=</span> <span class="n">Schema</span><span class="p">.</span><span class="na">recordOf</span><span class="p">(</span><span class="s">&quot;exampleSchema&quot;</span><span class="p">,</span>
                                 <span class="n">Schema</span><span class="p">.</span><span class="na">Field</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="s">&quot;id&quot;</span><span class="p">,</span> <span class="n">Schema</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">Schema</span><span class="p">.</span><span class="na">Type</span><span class="p">.</span><span class="na">INT</span><span class="p">)),</span>
                                 <span class="n">Schema</span><span class="p">.</span><span class="na">Field</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="s">&quot;name&quot;</span><span class="p">,</span> <span class="n">Schema</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">Schema</span><span class="p">.</span><span class="na">Type</span><span class="p">.</span><span class="na">STRING</span><span class="p">)),</span>
                                 <span class="n">Schema</span><span class="p">.</span><span class="na">Field</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="s">&quot;date&quot;</span><span class="p">,</span> <span class="n">Schema</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">Schema</span><span class="p">.</span><span class="na">LogicalType</span><span class="p">.</span><span class="na">DATE</span><span class="p">)),</span>
                                 <span class="n">Schema</span><span class="p">.</span><span class="na">Field</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="s">&quot;time-millis&quot;</span><span class="p">,</span> <span class="n">Schema</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">Schema</span><span class="p">.</span><span class="na">LogicalType</span><span class="p">.</span><span class="na">TIME_MILLIS</span><span class="p">)),</span>
                                 <span class="n">Schema</span><span class="p">.</span><span class="na">Field</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="s">&quot;time-micros&quot;</span><span class="p">,</span> <span class="n">Schema</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">Schema</span><span class="p">.</span><span class="na">LogicalType</span><span class="p">.</span><span class="na">TIME_MICROS</span><span class="p">)),</span>
                                 <span class="n">Schema</span><span class="p">.</span><span class="na">Field</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="s">&quot;ts-millis&quot;</span><span class="p">,</span> <span class="n">Schema</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">Schema</span><span class="p">.</span><span class="na">LogicalType</span><span class="p">.</span><span class="na">TIMESTAMP_MILLIS</span><span class="p">)),</span>
                                 <span class="n">Schema</span><span class="p">.</span><span class="na">Field</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="s">&quot;ts-micros&quot;</span><span class="p">,</span> <span class="n">Schema</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">Schema</span><span class="p">.</span><span class="na">LogicalType</span><span class="p">.</span><span class="na">TIMESTAMP_MICROS</span><span class="p">)));</span>
</pre></div>
</div>
<p>To set a record field for a logical type:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="n">StructuredRecord</span> <span class="n">record</span> <span class="o">=</span> <span class="n">StructuredRecord</span><span class="p">.</span><span class="na">builder</span><span class="p">(</span><span class="n">schema</span><span class="p">)</span>
      <span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="s">&quot;id&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
      <span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="s">&quot;name&quot;</span><span class="p">,</span> <span class="s">&quot;alice&quot;</span><span class="p">)</span>
      <span class="c1">// set date to August 30th, 2018</span>
      <span class="p">.</span><span class="na">setDate</span><span class="p">(</span><span class="s">&quot;date&quot;</span><span class="p">,</span> <span class="n">LocalDate</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="mi">2018</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">30</span><span class="p">))</span>
      <span class="c1">// set time in millis to 11.0.0.111 hours</span>
      <span class="p">.</span><span class="na">setTime</span><span class="p">(</span><span class="s">&quot;time-millis&quot;</span><span class="p">,</span> <span class="n">LocalTime</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">111</span> <span class="o">*</span> <span class="mi">1000</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">))</span>
      <span class="c1">// set time in millis to 11.0.0.111111 hours</span>
      <span class="p">.</span><span class="na">setTime</span><span class="p">(</span><span class="s">&quot;time-micros&quot;</span><span class="p">,</span> <span class="n">LocalTime</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">111111</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">))</span>
      <span class="c1">// set timestamp in millis to November 11, 2018 11:11:11.123 UTC</span>
      <span class="p">.</span><span class="na">setTimestamp</span><span class="p">(</span><span class="s">&quot;ts-millis&quot;</span><span class="p">,</span>
                     <span class="n">ZonedDateTime</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="mi">2018</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">123</span> <span class="o">*</span> <span class="mi">1000</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">,</span> <span class="n">ZoneId</span><span class="p">.</span><span class="na">ofOffset</span><span class="p">(</span><span class="s">&quot;UTC&quot;</span><span class="p">,</span> <span class="n">ZoneOffset</span><span class="p">.</span><span class="na">UTC</span><span class="p">)))</span>
      <span class="c1">// set timestamp in micros to November 11, 2018 11:11:11.123456 UTC</span>
      <span class="p">.</span><span class="na">setTimestamp</span><span class="p">(</span><span class="s">&quot;ts-micros&quot;</span><span class="p">,</span>
                     <span class="n">ZonedDateTime</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="mi">2018</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">123456</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">,</span> <span class="n">ZoneId</span><span class="p">.</span><span class="na">ofOffset</span><span class="p">(</span><span class="s">&quot;UTC&quot;</span><span class="p">,</span> <span class="n">ZoneOffset</span><span class="p">.</span><span class="na">UTC</span><span class="p">)))</span>
      <span class="p">.</span><span class="na">build</span><span class="p">();</span>
</pre></div>
</div>
<p>To read a logical type from a record:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="n">LocalDate</span> <span class="n">localDate</span> <span class="o">=</span> <span class="n">record</span><span class="p">.</span><span class="na">getDate</span><span class="p">(</span><span class="s">&quot;date&quot;</span><span class="p">);</span>
<span class="n">LocalTime</span> <span class="n">localTimeMillis</span> <span class="o">=</span> <span class="n">record</span><span class="p">.</span><span class="na">getTime</span><span class="p">(</span><span class="s">&quot;time-millis&quot;</span><span class="p">);</span>
<span class="n">LocalTime</span> <span class="n">localTimeMicros</span> <span class="o">=</span> <span class="n">record</span><span class="p">.</span><span class="na">getTime</span><span class="p">(</span><span class="s">&quot;time-micros&quot;</span><span class="p">);</span>
<span class="n">ZonedDateTime</span> <span class="n">timestampMillis</span> <span class="o">=</span> <span class="n">record</span><span class="p">.</span><span class="na">getTimestamp</span><span class="p">(</span><span class="s">&quot;ts-millis&quot;</span><span class="p">);</span>
<span class="n">ZonedDateTime</span> <span class="n">timestampMicros</span> <span class="o">=</span> <span class="n">record</span><span class="p">.</span><span class="na">getTimestamp</span><span class="p">(</span><span class="s">&quot;ts-micros&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>Please note that logical types such as Date, Time and Timestamp are internally represented as primitive types.
Therefore these types can be set or retrieved as primitive types in structured record. For example:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="n">StructuredRecord</span> <span class="n">record</span> <span class="o">=</span> <span class="n">StructuredRecord</span><span class="p">.</span><span class="na">builder</span><span class="p">(</span><span class="n">schema</span><span class="p">)</span>
        <span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="s">&quot;id&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
        <span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="s">&quot;name&quot;</span><span class="p">,</span> <span class="s">&quot;alice&quot;</span><span class="p">)</span>
        <span class="c1">// set number of days since epoch representing November 30th, 2018</span>
        <span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="s">&quot;date&quot;</span><span class="p">,</span> <span class="mi">17773</span><span class="p">)</span>
        <span class="c1">// set time in milli seconds representing 11.0.0.111 hours</span>
        <span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="s">&quot;time-millis&quot;</span><span class="p">,</span> <span class="mi">39600111L</span><span class="p">)</span>
        <span class="c1">// set time in micro seconds representing 11.0.0.111111 hours</span>
        <span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="s">&quot;time-micros&quot;</span><span class="p">,</span> <span class="mi">39600111111L</span><span class="p">)</span>
        <span class="c1">// set timestamp in milli seconds representing November 11, 2018 11:11:11.123 UTC</span>
        <span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="s">&quot;ts-millis&quot;</span><span class="p">,</span> <span class="mi">1541934671123L</span><span class="p">)</span>
        <span class="c1">// set timestamp in micro seconds representing November 11, 2018 11:11:11.123456 UTC</span>
        <span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="s">&quot;ts-micros&quot;</span><span class="p">,</span> <span class="mi">1541934671123456L</span><span class="p">)</span>
        <span class="p">.</span><span class="na">build</span><span class="p">();</span>

<span class="c1">// number of days since Unix epoch.</span>
<span class="kt">int</span> <span class="n">date</span> <span class="o">=</span> <span class="n">record</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="s">&quot;date&quot;</span><span class="p">);</span>
</pre></div>
</div>
</div>
</div>

</div>
    <div class="col-md-2">
      <div id="right-sidebar" class="bs-sidenav scrollable-y" role="complementary">
        <div id="localtoc-scrollspy">
        </div>
      </div>
    </div></div>
</div>
<!-- block main content end -->
<!-- block footer -->
<footer class="footer">
      <div class="container">
        <div class="row">
          <div class="col-md-2 footer-left"><a title="Developing Plugins" href="index.html" />Previous</a></div>
          <div class="col-md-8 footer-center"><a class="footer-tab-link" href="../../table-of-contents/../../reference-manual/licenses/index.html">Copyright</a> &copy; 2014-2020 Cask Data, Inc.&bull; <a class="footer-tab-link" href="//docs.cask.co/cdap/6.1.1/cdap-docs-6.1.1-web.zip" rel="nofollow">Download</a> an archive or
<a class="footer-tab-link" href="//docs.cask.co/cdap">switch the version</a> of the documentation
          </div>
          <div class="col-md-2 footer-right"><a title="Creating a Plugin" href="creating-a-plugin.html" />Next</a></div>
        </div>
      </div>
    </footer>
<!-- block footer end -->
<script type="text/javascript" src="../../_static/bootstrap-3.3.6/js/bootstrap.min.js"></script><script type="text/javascript" src="../../_static/js/bootstrap-sphinx.js"></script><script type="text/javascript" src="../../_static/js/abixTreeList-2.js"></script><script type="text/javascript" src="../../_static/js/cdap-dynamicscrollspy-4.js"></script><script type="text/javascript" src="../../_static/js/cdap-version-menu.js"></script><script type="text/javascript" src="../../_static/js/copy-to-clipboard.js"></script><script type="text/javascript" src="../../_static/js/jquery.mousewheel.min.js"></script><script type="text/javascript" src="../../_static/js/jquery.mCustomScrollbar.js"></script><script type="text/javascript" src="../../_static/js/js.cookie.js"></script><script type="text/javascript" src="../../_static/js/tabbed-parsed-literal-0.2.js"></script><script type="text/javascript" src="../../_static/js/cdap-onload-javascript.js"></script><script type="text/javascript" src="../../_static/js/cdap-version-menu.js"></script>
    <script src="https://cdap.gitee.io/docs/cdap/json-versions.js"/></script>
  </body>
</html>